// 默认参数
let defaultsProp = {
  unitToConvert: 'px',
  viewportWidth: 1920,
  unitPrecision: 5,
  viewportUnit: 'vw',
  fontViewportUnit: 'vw',
  minPixelValue: 1,
  // exclude: [/src\/pages\/screen/],
  exclude: [],
};

function toFixed(number, precision) {
  var multiplier = Math.pow(10, precision + 1),
    wholeNumber = Math.floor(number * multiplier);
  return (Math.round(wholeNumber / 10) * 10) / multiplier;
}

function createPxReplace(
  viewportSize,
  minPixelValue,
  unitPrecision,
  viewportUnit
) {
  return function ($0, $1) {
    if (!$1) return;
    var pixels = parseFloat($1);
    if (pixels <= minPixelValue) return;
    return toFixed((pixels / viewportSize) * 100, unitPrecision) + viewportUnit;
  };
}
const templateReg = /<template>([\s\S]+)<\/template>/gi;
const scriptReg = /<script([\s\S]+)<\/script>/gi;
const styleReg = /<style([\s\S]+)<\/style>/gi;
const pxGlobalReg = /(\d+)px/gi;

function isExclude(reg, file) {
  if (Object.prototype.toString.call(reg) !== '[object RegExp]') {
    throw new Error('options.exclude should be RegExp.');
  }
  return file.match(reg) !== null;
}

// 生成插件的工厂方法
const stylePxToVw = (customOptions = defaultsProp) => {
  // 返回插件
  return {
    // 插件名称
    name: 'postcss-px-to-viewport',

    // transform 钩子
    async transform(code, id) {
      let _source = '';
      if (customOptions.exclude && id) {
        if (
          Object.prototype.toString.call(customOptions.exclude) ===
          '[object RegExp]'
        ) {
          if (isExclude(customOptions.exclude, id)) return { code };
        } else if (
          Object.prototype.toString.call(customOptions.exclude) ===
          '[object Array]'
        ) {
          for (let i = 0; i < customOptions.exclude.length; i++) {
            if (isExclude(customOptions.exclude[i], id)) return { code };
          }
        } else {
          throw new Error('options.exclude should be RegExp or Array.');
        }
      }
      if (/.vue$/.test(id)) {
        let _source = '';
        let _script = '';
        if (templateReg.test(code)) {
          _source = code.match(templateReg)[0];
        }
        if (scriptReg.test(code)) {
          _script = code.match(scriptReg)[0];
        }
        if (styleReg.test(code)) {
          _script = code.match(styleReg)[0];
        }
        if (pxGlobalReg.test(_source)) {
          let $_source = _source.replace(
            pxGlobalReg,
            createPxReplace(
              customOptions.viewportWidth,
              customOptions.minPixelValue,
              customOptions.unitPrecision,
              customOptions.viewportUnit
            )
          );

          code = code.replace(_source, $_source);
        }
        if (pxGlobalReg.test(_script)) {
          let $_script = _script.replace(
            pxGlobalReg,
            createPxReplace(
              customOptions.viewportWidth,
              customOptions.minPixelValue,
              customOptions.unitPrecision,
              customOptions.viewportUnit
            )
          );

          code = code.replace(_script, $_script);
        }
      }
      return {
        code,
      };
    },
  };
};

export default stylePxToVw;
